<template>
    <div>
        <!-- 弹出层 -->
        <a-modal title="编辑用户信息" @cancel="btnCancel" @ok="btnOk" v-model:visible="showDialogComputed">
            <!-- labelCol定义 表单中左侧标题的一个宽度 -->
            <a-form :labelCol="{ span: 4 }">
                <a-form-item label="头像">
                    <img :src="uploadAvatarImage" style="height: 60px; width: 60px;" alt="" v-if="uploadAvatarImage">
                    <img :src="formData.avatar" style="height: 60px; width: 60px;" alt="" v-else>
                    <a-upload class="upload" v-model:file-list="fileList" name="file" :action="getIMAGEURL()"
                        :headers="headers" @change="handleChange">
                        <a-button>
                            <upload-outlined></upload-outlined>
                            更换头像
                        </a-button>
                    </a-upload>
                </a-form-item>
                <a-form-item label="账号" name="account" v-bind="form.validateInfos.account">
                    <a-input v-model:value="formData.account" placeholder="请输入账号"></a-input>
                </a-form-item>
                <a-form-item label="角色">
                    <!-- <a-input v-model:value="formData.role" placeholder="请输入角色"></a-input> -->
                    <a-space>
                        <a-select v-model:value="value" style="width: 120px" :options="options"
                            @change="handleChangeSelect">
                        </a-select>
                    </a-space>
                </a-form-item>
                <a-form-item label="菜单权限">
                    <div>
                        <a-checkbox v-model:checked="meunState.checkAll" :indeterminate="meunState.indeterminate"
                            @change="onCheckAllMeunChange">
                            全选
                        </a-checkbox>
                    </div>
                    <a-divider />
                    <a-checkbox-group v-model:value="meunState.checkedList" :options="meunOptions" />
                </a-form-item>
                <a-form-item label="按钮权限">
                    <div>
                        <a-checkbox v-model:checked="buttonState.checkAll" :indeterminate="buttonState.indeterminate"
                            @change="onCheckAllButtonChange">
                            全选
                        </a-checkbox>
                    </div>
                    <a-divider />
                    <a-checkbox-group v-model:value="buttonState.checkedList" :options="buttonOptions" />
                </a-form-item>
                <a-form-item label="注册时间" name="createAt">
                    <a-input disabled v-model:value="formData.createdAt"></a-input>
                </a-form-item>
            </a-form>
        </a-modal>
    </div>
</template>

<script setup lang="ts">
import type { IAdmin, IpermissionItem } from '@/types/user'
import { UploadOutlined } from '@ant-design/icons-vue'
import dayjs from 'dayjs'
import { Form, message } from 'ant-design-vue'
import type { UploadChangeParam, SelectProps } from 'ant-design-vue'
import { getIMAGEURL } from '@/utils/getImageUrl'
import { useUserStore } from '@/stores'


// 父子组件通信 父：v-model:showDialog="showDialog"
// 子： emits('update:showDialog','传给父组件的值')

// Props是单向数据流只能在父组件修改，不能在子组件修改
const { showDetail, id } = defineProps<{
    showDetail: boolean,
    id: number
}>()

// 得到一个事件触发器
const emits = defineEmits<{
    (e: 'update:showDetail', val: Boolean): void,
    (e: 'addSuccess'): void,
}>()
let formData = reactive<IAdmin>({})


const showDialogComputed = computed({
    get() {
        return showDetail  // 读取Props传来的值
    },
    set(val) {
        // val 是需要从父组件去入手修改 子传父
        emits('update:showDetail', val) // 告诉父组件 去修改showDialog的值
    }
})

watch([() => showDetail, () => id], async () => {
    if (showDetail && id) {
        const res = await findByIdAdmin(id)
        formData.id = res.data.admin.id
        formData.avatar = res.data.admin.avatar
        formData.account = res.data.admin.account
        formData.roles = res.data.admin.roles
        formData.roleId = res.data.admin.roleId
        roleId.value = res.data.admin.roleId as number
        formData.createdAt = dayjs(res.data.admin.createdAt).format('YYYY-MM-DD')
        meunState.checkedList = res.data.admin.menus as string[]
        buttonState.checkedList = res.data.admin.points as string[]
    }
})

type Role = { value: number, label: string }
const roleList = ref<Role[]>([])
const getRoleListData = async () => {
    const res = await getRoleList()
    res.data.forEach(d => {
        roleList.value.push({ value: d.id, label: d.name })
    })
}
const meunsPermissionList = ref<IpermissionItem[]>([])
const buttonPermissionList = ref<IpermissionItem[]>([])
const userStore = useUserStore()

const getPermissionData = async () => {
    const res = await getPermissionList()
    meunsPermissionList.value = res.data.routes
    buttonPermissionList.value = res.data.buttons
    meunOptions = res.data.routes.map(i => i.name)
    res.data.buttons.forEach(i => {
        if (userStore.user?.role.name && userStore.user?.role.name !== '超级管理员') {
            if (i.name !== "PERMISSION_EDIT") {
                buttonOptions.push(i.name)
            }
        } else {
            buttonOptions.push(i.name)
        }
    })
}

onMounted(async () => {
    await getRoleListData()
    await getPermissionData()
})

const options = roleList
const roleId = ref(0)
const value = ref({ value: roleId })

const handleChangeSelect: SelectProps['onChange'] = value => {
    formData.roleId = value as number
};

// 菜单权限
let meunOptions: string[] = []
// 按钮权限
let buttonOptions: string[] = []
const meunState = reactive({
    indeterminate: true,
    checkAll: false,
    checkedList: [] as string[],
});
const buttonState = reactive({
    indeterminate: true,
    checkAll: false,
    checkedList: [] as string[],
});

const onCheckAllMeunChange = (e: any) => {
    Object.assign(meunState, {
        checkedList: e.target.checked ? meunOptions : [],
        indeterminate: false,
    });
};

const onCheckAllButtonChange = (e: any) => {
    Object.assign(buttonState, {
        checkedList: e.target.checked ? meunOptions : [],
        indeterminate: false,
    });
};
watch(
    () => meunState.checkedList,
    val => {
        meunState.indeterminate = !!val.length && val.length < meunOptions.length;
        meunState.checkAll = val.length === meunOptions.length;
    },
);
watch(
    () => buttonState.checkedList,
    val => {
        buttonState.indeterminate = !!val.length && val.length < meunOptions.length;
        buttonState.checkAll = val.length === meunOptions.length;
    },
);
//

const btnCancel = () => {
    form.resetFields() // 清除数据 并且清除校验
}

const btnOk = async () => {
    const menus: number[] = []
    const points: number[] = []
    meunState.checkedList.forEach(i => {
        meunsPermissionList.value.forEach((m: { name: string, id: number }) => {
            if (m.name === i) {
                menus.push(m.id)
            }
        })
    })

    buttonState.checkedList.forEach(i => {
        buttonPermissionList.value.forEach((m: { name: string, id: number }) => {
            if (m.name === i) {
                points.push(m.id)
            }
        })
    })

    await form.validate()
    // 到此不证明校验通过
    const res = await updatedAdmin({ ...formData, menus, points })
    // 校验通知
    res.code === 201 ? message.success('更新成功') : message.error('更新失败'),

        btnCancel(),

        // 关闭弹层
        showDialogComputed.value = false

    // 新增成功 只是后端接口插入了一条数据- 前端并没有更新- 重新拉取数据
    // 告诉父组件
    emits('addSuccess')

}

// 校验规则
const rules = reactive({
    account: [
        { required: true, message: '账号不能为空', trigger: 'blur' },
        { min: 4, max: 10, message: '账号4-10位' }
    ]
})

// 引入antd的From下的useForm方法把校验规则绑定在formData.value上
const form = Form.useForm(formData, rules)

const uploadAvatarImage = ref<string>('')

// 头像上传
const handleChange = (info: UploadChangeParam) => {
    if (info.file.status !== 'uploading') {
        console.log(info.file, info.fileList);
        uploadAvatarImage.value = info.file.response.data.url
        formData.avatar = uploadAvatarImage.value
    }
    if (info.file.status === 'done') {
        message.success(`${info.file.name} file uploaded successfully`);
    } else if (info.file.status === 'error') {
        message.error(`${info.file.name} file upload failed.`);
    }
};

const fileList = ref([]);
const headers = reactive({
    authorization: 'authorization-text',
})

</script>


<style scoped lang="less">
.upload {
    margin-left: 20px;
}
</style>